<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8"/>
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
        <title>AJ IAM /用户系统的架构设计与实现策略-用户模型</title>
        <meta name="description" content="轻量级用户认证系统 用户系统的架构设计与实现策略-用户模型"/>
        <meta name="keywords" content="用户, 认证, 会员系统, IAM, AJ-IAM, 用户模型"/>
        <meta name="viewport" content="width=device-width, initial-scale=1"/>
        <link rel="preconnect" href="https://fonts.googleapis.com" />
        <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
        <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@200..900&family=Noto+Serif:ital,wght@0,100..900;1,100..900&display=swap&family=Noto+Sans+SC:wght@100..900&display=swap" />
        <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@100..900&family=Noto+Serif:ital,wght@0,100..900;1,100..900&display=swap" />
        <link rel="stylesheet" href="https://framework.ajaxjs.com/static/new-ui/css/common.css" />
        <link rel="stylesheet" href="/asset/main.css"/>
        <link rel="icon" type="image/x-icon" href="https://framework.ajaxjs.com/aj-logo/logo.ico"/>
        <script src="https://framework.ajaxjs.com/static/aj-docs/common.js"></script>
        <script>
            var _hmt = _hmt || [];
            (function() {
              var hm = document.createElement("script");
              hm.src = "https://hm.baidu.com/hm.js?54c70624d18784ca7539c358f583133d";
              var s = document.getElementsByTagName("script")[0];
              s.parentNode.insertBefore(hm, s);
            })();
        </script>
    </head>
    <body>
        <nav>
            <div>
                <div class="links">
                    <a href="/">🏠 首页</a>
                    | ⚙️ 源码:
                    <a target="_blank" href="https://github.com/lightweight-component/aj-iam">Github</a>/<a target="_blank" href="https://gitcode.com/lightweight-component/aj-iam">Gitcode</a>
                </div>
                <h1><img src="https://framework.ajaxjs.com/aj-logo/logo.png" style="vertical-align: middle;height: 45px;margin-bottom: 6px;" /> AJ IAM</h1>
                <h3>轻量级用户认证系统</h3>
            </div>
        </nav>
        <div>
            <menu>
                
                <ul>
                    <li class="selected">
                        <a href="/">首页</a>
                    </li>
                </ul>
                <h3>开发心得</h3>
                <ul>
                    <li>
                        <a href="/developer/user-cn">用户系统</a>
                    </li>
                    <li>
                        <a href="/developer/model-cn">用户权限模型</a>
                    </li>
                </ul>
                <h3>部署</h3>
                <ul>
                      <li>
                           <a href="/handbook/deploy-cn">部署方式</a>
                      </li>
                      <li>
                           <a href="/handbook/dev-cn">开发环境部署</a>
                      </li>
                </ul>

                <h3>其他</h3>
                <ul>
                    <li><a href="/misc/contact-cn">联系方式</a></li>
                </ul>
            </menu>
            <article class="aj-text chinese">
                <h1>用户系统的架构设计与实现策略-用户模型</h1>
<p>一个用户系统除了基本的用户业务功能，还应囊括用户的权限设计及其实现。这本文中我们将探讨一下关于用户权限的设计与实现方法论。</p>
<h1>简介</h1>
<p>在构建现代应用系统的过程中，很少有设计决策会像访问控制机制那样，对安全性、可扩展性和用户体验产生如此深远的影响。很多开发团队最初会选择一个简单的 RBAC（基于角色的访问控制）模型，并将授权逻辑直接写入应用代码中。然而，随着业务需求不断演进，通常需要融合 RBAC、ABAC 和 ReBAC 的多种机制，才能满足实际场景中的复杂授权需求。</p>
<p>很多人误以为这些模型是彼此独立、非此即彼的选择，认为企业只需选定一种并长期使用。但现实中，开发团队往往是根据不断变化的业务需求，逐步叠加和调整不同的控制模型，形成更为灵活和精细的权限体系。</p>
<p>本文将带你深入了解当前主流的三种访问控制模型——RBAC（基于角色）、ABAC（基于属性）和 ReBAC（基于关系），分析它们各自的优缺点以及适用场景。我们还将帮助你判断哪一种模型，或者哪几种的组合，最契合你的产品需求，并提供一些实用的实现建议。</p>
<h1>了解访问控制的主流模型</h1>
<p>访问控制本质上是在回答一个看似简单的问题：“谁可以对哪些资源执行什么操作？”<br>
这个问题的答案取决于用户身份、资源组织方式以及相关的上下文信息（如所属组织、时间、地理位置等）。</p>
<h2>基于角色的访问控制（RBAC）</h2>
<p>RBAC（Role-Based Access Control）是目前应用最广泛的访问控制模型。它的核心思想是将权限分配给“角色”，而用户通过被赋予某个角色来继承相应的权限。在 RBAC 模型中，用户拥有明确的角色，这些角色决定了他们可以访问哪些数据。这种模型特别适用于具有清晰职责划分和层级结构的组织。举个例子，在一个内容管理系统中：</p>
<ul>
<li>编辑可以创建和编辑内容</li>
<li>审核人员可以批准或驳回内容</li>
<li>管理员可以管理用户和系统设置</li>
</ul>
<p>RBAC 的逻辑清晰、易于理解，因此很多开发团队在自行实现权限系统时往往以此为起点。然而RBAC 无法满足现代应用程序对细粒度权限控制的需求。因此许多团队会进一步引入基于属性或关系的模型来扩展其权限体系。</p>
<h2>基于关系的访问控制（ReBAC）</h2>
<p>ReBAC（Relationship-Based Access Control）关注的是系统中不同实体之间的关系。它不依赖于直接授权或属性判断，而是通过用户与资源之间的关联来决定访问权限。</p>
<p>我们继续以 RBAC 中提到的内容管理系统为例。假设某位用户在系统中创建了一个文件夹，并存储了一些文档。如果你拥有该文件夹的查看权限，那么你也应该能够查看该文件夹下的所有文档。这就需要引入 ReBAC：这意味着你不仅要定义角色，还要根据资源之间的关系来组织权限——在这个例子中，就是文档与文件夹之间的归属关系。</p>
<p>ReBAC 非常适合处理具有复杂层级和高度关联的数据场景。例如在文档管理系统中，它可以轻松表达诸如“用户可以访问自己参与项目的全部文档”这样的规则，而无需为每一份文档单独打标签。</p>
<h2>基于属性的访问控制（ABAC）</h2>
<p>ABAC（Attribute-Based Access Control）采用一种更动态的方式来决策访问权限，它根据用户、资源、操作以及环境等属性进行判断。它是目前灵活性最强的访问控制模型，但同时也是实施和维护成本最高的。</p>
<p>ABAC 允许通过条件和属性实现非常精细的控制。再来看我们的内容管理系统。有些文档可能被标记为“公开”，无论它们存放在哪个文件夹里，所有用户都应该有权查看。这时就可以在授权逻辑中加入“公开”这一文档属性作为判断依据。</p>
<h1>RBAC 与 ABAC：当角色权限不够用时</h1>
<p>RBAC 虽然为访问控制提供了坚实的基础，但随着应用功能日益复杂，它也逐渐暴露出一些局限性。例如，所需的“角色”数量可能急剧膨胀给运维带来沉重负担；或者角色粒度太粗，授予了本不该拥有的权限，造成安全隐患。</p>
<h2>RBAC 的局限性</h2>
<p>在访问控制需求与组织架构高度一致的情况下，RBAC 表现良好。但在以下场景中就显得力不从心：</p>
<ul>
<li>需要根据上下文动态判断权限</li>
<li>存在临时性的访问需求</li>
<li>需要更细粒度的权限控制</li>
<li>环境或业务频繁变化的系统</li>
</ul>
<p>当这些挑战出现时，很多企业开始转向 ABAC 模型。虽然 RBAC 和 ABAC 都用于保护系统和数据安全，但它们在权限分配和管理方式上存在显著差异。</p>
<h2>ABAC：强大而复杂的访问控制模型</h2>
<p>ABAC 在权限控制方面比 RBAC 更加精细，它通过多种属性来决策访问权限，包括：</p>
<ul>
<li><strong>用户属性</strong>：如部门、安全级别、地理位置</li>
<li><strong>资源属性</strong>：如密级、所有者、创建时间</li>
<li><strong>操作属性</strong>：如访问时间、之前的操作记录</li>
<li><strong>环境属性</strong>：如设备安全性、网络位置</li>
</ul>
<p>这种灵活性也带来了代价：相比 RBAC，ABAC 更难理解和维护。它需要更周密的设计，并且在审计和故障排查时也可能更加复杂。</p>
<hr>
<h1>ABAC vs. ReBAC：条件判断与关系推理</h1>
<p>除了 ABAC，RBAC 还有一个重要替代方案是 <strong>ReBAC</strong>。ABAC 和 ReBAC 都支持细粒度访问控制，但它们解决问题的方式截然不同。</p>
<h2>ABAC 的优势场景</h2>
<p>ABAC 特别适用于需要基于多个属性进行复杂逻辑判断的场景。比如在一个复杂的系统中，访问权限取决于时间、地点和用户状态等多种因素。举个例子：</p>
<blockquote>
<p>“只有在午夜之后，并且用户坐在吧台前，访客才可以点特定饮品。”</p>
</blockquote>
<p>这个策略结合了时间属性、位置属性和用户属性，正是 ABAC 的典型应用场景。</p>
<h2>ReBAC 的核心优势</h2>
<p>ReBAC 利用数据模型中的实体关系来简化访问控制。它不像 ABAC 那样依赖属性标签，而是通过实体之间的关联来进行权限判断。设想一个名叫 Jay 的用户，他拥有一个储物柜，里面放着各种物品。如果使用 ABAC，你可能需要为每个物品打上 <code>Owner=Jay</code> 的标签。而使用 ReBAC，只需定义一条规则：</p>
<blockquote>
<p>“访客可以访问自己储物柜内的所有物品。”</p>
</blockquote>
<p>Jay、他的储物柜以及其中的物品之间形成的自然关系，就构成了清晰的访问控制结构。</p>
<p>ReBAC 尤其适用于以下类型的系统：</p>
<ul>
<li>层级结构系统</li>
<li>社交网络</li>
<li>文档管理系统</li>
<li>团队协作工具</li>
<li>具有复杂实体关系的任何应用</li>
</ul>
<h1>模型对比：实用分析</h1>
<table>
<thead>
<tr>
<th>维度</th>
<th>RBAC<br>（基于角色的访问控制）</th>
<th>ReBAC<br>（基于关系的访问控制）</th>
<th>ABAC<br>（基于属性的访问控制）</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>概念复杂度</strong></td>
<td>低</td>
<td>中等至高</td>
<td>高</td>
</tr>
<tr>
<td><strong>适用场景</strong></td>
<td>基于角色的组织架构权限管理</td>
<td>需要根据实体关系控制访问的场景</td>
<td>需要结合上下文动态判断权限的场景</td>
</tr>
<tr>
<td><strong>权限粒度</strong></td>
<td>较粗略；容易出现“角色爆炸”或权限过宽的问题</td>
<td>中等到较高</td>
<td>高</td>
</tr>
<tr>
<td><strong>典型用例</strong></td>
<td>销售人员可以查看所有销售数据</td>
<td>销售经理可以查看其直接下属负责的所有销售数据</td>
<td>销售经理只能在工作时间，通过公司电脑查看其直接下属负责的销售数据</td>
</tr>
<tr>
<td><strong>自研实现难度</strong></td>
<td>低至中等</td>
<td>中等至高</td>
<td>高</td>
</tr>
<tr>
<td><strong>实现难度</strong></td>
<td>低</td>
<td>低至中等</td>
<td>低至中等</td>
</tr>
</tbody>
</table>
<h1>实际应用场景解析</h1>
<p>总结来说，不同的访问控制模型适用于不同类型的应用场景：</p>
<ul>
<li><strong>RBAC</strong>：适用于组织架构清晰的企业级应用</li>
<li><strong>ABAC</strong>：适用于需要复杂条件判断的系统，如金融、医疗领域</li>
<li><strong>ReBAC</strong>：适用于社交平台、文档管理系统和协作工具</li>
</ul>
<h1>混合方案：融合多种模型的优势</h1>
<p>在实际开发中，许多复杂的系统会结合使用 RBAC、ABAC 和 ReBAC，以满足不同层次的权限控制需求。通常的做法是：</p>
<ul>
<li>使用 <strong>RBAC</strong> 管理基础权限</li>
<li>使用 <strong>ABAC</strong> 处理上下文敏感型权限</li>
<li>使用 <strong>ReBAC</strong> 管理实体之间的关系型权限</li>
</ul>
<h2>以 RBAC 作为基础框架</h2>
<p>RBAC 是实现粗粒度访问控制的理想选择。它逻辑清晰、易于理解，无论对管理员还是开发人员都非常友好，因此常常作为权限体系的起点。</p>
<p>✅ <strong>RBAC 示例场景</strong>：分析师可以查看所有报表</p>
<h2>引入 ABAC 提升灵活性</h2>
<p>当权限控制需要考虑时间、地点、资源状态等动态因素时，可以在 RBAC 的基础上引入 ABAC，从而增强权限策略的适应性。比如，一个基本角色可能被授予访问财务报表的权限，而通过 ABAC 可以进一步限制访问只能在特定时间、特定位置进行，或者根据报表的敏感级别进行动态授权。</p>
<p>✅ <strong>RBAC + ABAC 示例场景</strong>：分析师仅可在工作时间内查看报表</p>
<h2>利用 ReBAC 管理数据关系</h2>
<p>ReBAC 在处理基于数据结构的权限方面表现出色。很多系统会在 RBAC 和 ABAC 的基础上叠加 ReBAC，形成更完整的权限控制体系。例如 RBAC 和 ABAC 可以共同定义谁能访问哪些文件，而 ReBAC 则能自动识别“谁创建了该文件”、“谁属于某个团队”这样的关系，从而决定是否允许访问。</p>
<p>✅ <strong>RBAC + ReBAC 示例场景</strong>：经理可以访问其团队成员创建的所有文件</p>
<h2>三者结合：应对最复杂的权限需求</h2>
<p>在一些高度复杂的业务场景中单一模型已经无法满足需求，这时就需要将 RBAC、ABAC 和 ReBAC 三种模型结合起来使用。</p>
<p>✅ <strong>三者结合示例场景</strong>：医生只有在其所在科室内、处于值班状态，并且获得患者授权的情况下，才能访问患者病历信息</p>
<h1>实施访问控制的关键考量因素</h1>
<p>在实施访问控制机制时，需要综合考虑以下几个关键因素：</p>
<ul>
<li><strong>性能影响</strong>：复杂的权限检查可能会影响应用响应速度。</li>
<li><strong>开发体验</strong>：过于复杂的模型会拖慢开发进度。</li>
<li><strong>维护成本</strong>：权限规则需要定期审查和更新。</li>
<li><strong>可扩展性</strong>：你的访问控制模型应能随着应用的发展而灵活扩展。</li>
</ul>
<h2>授权即服务（Authorization-as-a-Service）模式</h2>
<p>许多企业尝试自行实现 ABAC 或 ReBAC 时，往往需要在服务中嵌入大量自定义逻辑，手动同步角色或关系数据，并在多个接口之间重复编写权限逻辑。正因如此越来越多组织开始采用“授权即服务”方案来简化权限管理。</p>
<p>这种架构将授权逻辑从应用程序代码中剥离出来，带来以下优势：</p>
<ul>
<li><strong>集中化策略管理</strong></li>
<li><strong>跨服务的一致性控制</strong></li>
<li><strong>更强的审计能力</strong></li>
<li><strong>更低的开发复杂度</strong></li>
</ul>
<p>理想的应用程序可以将多种访问控制模型组合使用：只需在一个地方声明式地定义角色、属性和关系，应用程序就会自动处理策略的执行、测试与传播。</p>
<h1>为你的应用选择合适的方案</h1>
<p>选择最合适的访问控制模型，取决于你的具体业务需求：</p>
<ul>
<li><strong>从数据模型出发</strong>：理解系统中的实体及其关系</li>
<li><strong>识别访问模式</strong>：用户如何与资源交互？</li>
<li><strong>考虑未来发展</strong>：你的访问控制需求是否会随时间变得更加复杂？</li>
<li><strong>评估实施资源</strong>：越复杂的模型，通常意味着越高的开发投入</li>
</ul>
<h2>决策辅助问题清单</h2>
<p>不同的访问控制模型在概念复杂度上有所差异：RBAC 最易理解和实现，ABAC 引入了条件逻辑，而 ReBAC 则建模了用户与资源之间的复杂关系。你可以思考以下几个问题来辅助决策：</p>
<ul>
<li>你们组织中的角色是否清晰且相对稳定？</li>
<li>权限判断是否依赖于时间、地点或资源状态等动态因素？</li>
<li>实体之间的关系是否是你数据模型的核心部分？</li>
<li>是否需要支持权限的委托或继承？</li>
</ul>
<p>在传统的自研系统中，这些问题都会直接影响开发和维护的成本。</p>
<p>而在理想的应用程序中应该解耦这些关注点。你仍需仔细思考哪些模型最适合你的应用场景 —— 但即便是最复杂的模型（如 ABAC），实现起来也变得简单得多。程序中应提供了一整套工具，让你能够统一、可测试、可持续地建模关系、条件和角色。</p>
<h1>总结</h1>
<p>在 RBAC、ABAC 和 ReBAC 之间进行选择，并不是为了找到“最好的”模型，而是为了找到最适合你应用场景的那一款。许多成功的系统都采用了多种模型的组合，在不同场景下发挥各自的优势。</p>
<p>随着应用系统越来越复杂、相互关联性增强，行业正在向 ABAC 和 ReBAC 这类更高级的访问控制模型转变。它们不仅提供了现代应用所需的细粒度控制，还能有效弥补传统 RBAC 的局限。无论你最终选择哪种模型，请记住：访问控制不仅是安全设计的核心环节，也是用户体验的重要组成部分。花时间设计一套合理的权限体系，将在整个应用生命周期中持续为你带来回报。</p>

            </article>
        </div>
        <footer>
             AJ-IAM，开源框架 <a href="https://framework.ajaxjs.com" target="_blank">AJ-Framework</a> 的一部分。联系方式：
             frank@ajaxjs.com，<a href="https://blog.csdn.net/zhangxin09" target="_blank">作者博客</a>
             <br />
             <br />
             Copyright © 2025 Frank Cheung. All rights reserved.
         </footer>
    </body>
</html>